[{"id":"1d802351.fc2c1d","type":"inject","z":"513581b9.a1b88","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"title\":\"Live Table\",\"subtitle\":\"Real-time tap flow rates at one second resolution.\",\"body\":\"\"}","payloadType":"json","x":210,"y":2760,"wires":[["a40f5e18.a99ed"]]},{"id":"a40f5e18.a99ed","type":"template","z":"513581b9.a1b88","name":"Live Table","field":"payload.body","fieldType":"msg","format":"html","syntax":"mustache","template":"\n\n  <script>\n    $(document).ready(function () {\n\n      var urlParams = new URLSearchParams(window.location.search);\n\n          \n            var form_data = {};\n            var form_url = '/api/devices/data?show='+urlParams.get('show');\n            var form_target = $(this).attr(\"target\") || \"result\";\n            var ftarget = \"#\" + form_target;\n            var form_method = \"GET\";\n            \n        //     $(\"#loadingimg\").show();\n            \n            $.ajax({\n                url: form_url, \n                type: form_method,      \n                data: form_data,     \n                cache: false,\n                success: function(returnhtml){   \n                    \n                    //userdata = JSON.parse(returnhtml);\n                    \n                    \n                    var tdata = {};\n                    var cols = [];\n                    for(var dline in returnhtml.data) {\n                        \n                        //tabout += returnhtml.data[dline][0] + \"/\" + returnhtml.data[dline][1] + \"/\" + returnhtml.data[dline][2] + \"<br>\";\n                        var dev = returnhtml.data[dline][0].split(\"/\")[0] + \"_\" + returnhtml.data[dline][1];\n                        var ddata = tdata[dev] || {};\n                        var topid = returnhtml.data[dline][2].replace(\"/\",\"_\");\n                        ddata[topid] = returnhtml.data[dline];\n                        tdata[dev] = ddata;\n                        if (cols.indexOf(topid)==-1) { cols.push(topid); }\n                    }\n                    \n                                        \n                    cols.sort(function(a, b) {\n                        return a - b;\n                    });\n                                        \n                    var tabout = '<table id=\"dtable\" class=\"table table-striped table-bordered table-sm compact\" cellspacing=\"0\" width=\"100%\" style=\"font-size:16px;\">';\n                    \n                    tabout += \"<thead><tr><th>Device</th>\";\n                    for(var col in cols) {\n                            \n                            tabout += \"<th>\" + cols[col].replace(\"_\",\" \") + \"</th>\";\n                    }\n                    tabout += \"</tr></thead><tbody>\";\n                    for(var dline in tdata) {\n                        \n                        tabout += \"<tr><td>\" + dline.replace(\"_\",\" / \") + \"</td>\";\n                        for(var col in cols) {\n                            \n                            var vo = \"\";\n                            if (tdata[dline][cols[col]]) {\n                                vo = tdata[dline][cols[col]][4];\n                                \n                                vo = '<span class=\"key text_' + dline + \"_\" + cols[col] + '\">' + vo + '</span>';\n                            }\n                            \n                            tabout += \"<td>\" + vo + \"</td>\";\n                        }\n                        \n                         tabout += \"</tr>\";\n                    }\n                    tabout += \"</tbody><table>\";\n                    \n                    document.getElementById(\"dtablediv\").innerHTML = tabout ;\n                    \n                    var subtext = document.getElementById(\"dtablediv\").getElementsByTagName(\"svg\");\n        \t\t\tfor (var j = 0; j < subtext.length; j++) {\n        \t\t\t    //alert(subtext[j].style.fill);\n        \t\t\t     subtext[j].setAttribute(\"height\",\"100px\");\n        \t\t\t     subtext[j].setAttribute(\"width\",\"200px\");\n        \t\t\t}\n                    \n                       \n                    $('#dtable').DataTable({ \"lengthMenu\": [ 15, 20, 25, 50, 75, 100 ]} );\n                    document.getElementById(\"dtablediv\").style.display=\"inline\";\n                    \n                    \n                    startMQTT();\n             \n                    //$(ftarget).html(returnhtml);               \n                }           \n            });    \n            \n            // setTimeout( function () {\n                \n            //         $('#dtable').DataTable({ \"lengthMenu\": [ 15, 20, 25, 50, 75, 100 ]} );\n            //         document.getElementById(\"dtablediv\").style.display=\"inline\";\n                    \n            //   }, 100 );\n            \n\n    //   var table = $('#dtable').DataTable({         \n    //           \"lengthMenu\": [ 15, 20, 25, 50, 75, 100 ],\n    //           \"deferRender\": true\n    //       } );\n    //   $('.dataTables_length').addClass('bs-select');\n\n    //   setInterval( function () {\n    //       table.ajax.reload( null, false ); // user paging is not reset on reload\n    //   }, 30000 );\n\n   \n\n     \n      \n\n    });\n\n    // \"scrollX\": true,\n  </script>\n  \n    <style>\n        \n        table.dataTable.compact thead th, table.dataTable.compact thead td {\n            padding: 4px 16px 2px 2px;\n        }\n\n    </style>\n \n\n\n<style>\nspan * {\n    transition: all 2s;    \n}\n</style>\n\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js\" type=\"text/javascript\"></script>\n\n<script>\n\n\n\n\n\nvar urlParams = new URLSearchParams(window.location.search);\n\n\nvar mqttServer = urlParams.get('server') || \"\";\nvar mqttPort = urlParams.get('port') ||\"8081\";\nvar mqttUser = urlParams.get('user') || \"\";\nvar mqttPassword = urlParams.get('password') || \"\";\nvar mqttSSL = urlParams.get('ssl') || \"true\";\nif (mqttSSL==\"true\") { mqttSSL = true; } else { mqttSSL=false; }\n\nvar readings = {};\nvar mygauges = {};\n\n\nfunction hexdec (hexv) {\n    \n    var hexString = (hexv + '').replace(/[^a-f0-9]/gi, '')\n    return parseInt(hexString, 16);\n    \n  }\n  \n  function dechex (number) {\n    \n    if (number < 0) {\n      number = 0xFFFFFFFF + number + 1\n    }\n    var hx =  parseInt(number, 10).toString(16);\n    \n    if (hx.length==1) { hx = \"0\" + hx; }\n    return hx;\n  }\n  \n  function color_avg(color1,color2,factor) {\n  \n          // extract RGB values for color1.\n          \n          var r1 = color1.substr(1,2);\n          var g1 = color1.substr(3,2);\n          var b1 = color1.substr(5,2);\n          \n          var r2 = color2.substr(1,2);\n          var g2 = color2.substr(3,2);\n          var b2 = color2.substr(5,2);\n  \n          // get the average RGB values.\n          var r_avg = (hexdec(r1)*(1-factor)+hexdec(r2)*factor);\n          var g_avg = (hexdec(g1)*(1-factor)+hexdec(g2)*factor);\n          var b_avg = (hexdec(b1)*(1-factor)+hexdec(b2)*factor);\n  \n          // construct the result color.    \n          var color_avg = '#' + dechex(r_avg) + dechex(g_avg)+ dechex(b_avg);\n  \n          // return it.\n          return color_avg;\n  }\n  \n  \n  function tempColour(temp) {\n      \n      \n      \n      var values = parseFloat(temp);\n      \n      if(values==0) { return(\"#ffffff\"); }\n\n      var tempcolour = \"#ff6c6c\";\n  \n      var tv = Math.ceil(values / 10);\n  \n      var factr = 1 - (tv - (values / 10));\n  \n  \n      //if ($tv<1) { $tempcolour = '#57007f'; }\n      //elseif ($tv==1) { $tempcolour = color_avg(\"#57007f\",\"#140af7\",$factr); }\n      //elseif ($tv==2) { $tempcolour = color_avg(\"#140af7\",\"#008ef9\",$factr); }\n      \n      if (tv<1) { tempcolour = '#ffffff'; }\n      else if (tv==1) { tempcolour = color_avg(\"#ffffff\",\"#ffffff\",factr); }\n      else if (tv==2) { tempcolour = color_avg(\"#ffffff\",\"#008ef9\",factr); }\n      else if (tv==3) { tempcolour = color_avg(\"#008ef9\",\"#14fffb\",factr); }\n      else if (tv==4) { tempcolour = color_avg(\"#14fffb\",\"#66fe00\",factr); }\n      else if (tv==5) { tempcolour = color_avg(\"#66fe00\",\"#f7fe02\",factr); }\n      else if (tv==6) { tempcolour = color_avg(\"#f7fe02\",\"#fdbe10\",factr); }\n      else if (tv==7) { tempcolour = color_avg(\"#fdbe10\",\"#f08e12\",factr); }\n      else if (tv==8) { tempcolour = color_avg(\"#f08e12\",\"#ff4f19\",factr); }\n      else if (tv==9) { tempcolour = color_avg(\"#ff4f19\",\"#c90504\",factr); }\n      else if (tv>9) { tempcolour = \"#c90504\";  }\n  \n              \n      return(tempcolour);\n      \n  }\n  \n\n\n\n</script>\n\n\n\n\n<script type=\"text/javascript\">\n\nvar a = new Date();\n \t\t\nvar subscriptions = \"\";\nvar svgtopics = \"\";\n// Create a client instance\n//client = new Paho.MQTT.Client(\"hw3.ddns.net\", Number(8083), \"cl\"+a.getTime());\n\nvar serverdes =\"\";\n\nfunction changeserver() {\n    \n    \n    var n = parseInt(document.getElementById(\"serverserver\").value);\n    \n    if (userdata.networks[n].server) { mqttServer = userdata.networks[n].server; }\n    if (userdata.networks[n].port) { mqttPort = userdata.networks[n].port; }\n    if (userdata.networks[n].user) { mqttUser = userdata.networks[n].user; }\n    if (userdata.networks[n].password) { mqttPassword = userdata.networks[n].password; }\n    \n    connectMQTT();\n}\n\nfunction connectMQTT() {\n    \n    \n                    client = new Paho.MQTT.Client(mqttServer, Number(mqttPort), \"cl\"+a.getTime());\n                \n                    client.onConnectionLost = onConnectionLost;\n                    client.onMessageArrived = onMessageArrived;\n                    \n                    if (mqttSSL==true || mqttSSL==\"true\") { mqttSSL = true; } else { mqttSSL=false; }\n                    \n                    serverdes = mqttUser + \"@\" + mqttServer + \":\" + mqttPort;\n                    document.getElementById(\"infodiv\").innerHTML = \" connecting to \" + serverdes;\n                    \n                    client.connect({onSuccess:onConnect, userName:mqttUser, password:mqttPassword, useSSL:mqttSSL });\n    \n    \n}\n\t\nvar userdata = {};\t\n\t\n\tfunction startMQTT() {\n    \n        // $(\"form[ajax=true]\").submit(function(e) {\n            \n        //     //alert(\"submit\");\n            \n        //     e.preventDefault();\n            \n            \n            var form_data = {};\n            var form_url = \"/api/user\";\n            var form_target = $(this).attr(\"target\") || \"result\";\n            var ftarget = \"#\" + form_target;\n            var form_method = \"GET\";\n            \n        //     $(\"#loadingimg\").show();\n            \n            $.ajax({\n                url: form_url, \n                type: form_method,      \n                data: form_data,     \n                cache: false,\n                success: function(returnhtml){   \n                    \n                    userdata = JSON.parse(returnhtml);\n                    \n                    var myn=0;\n                    for (var n in userdata.networks) {\n                        \n                        if ((\" \" + urlParams.get('show')).indexOf(userdata.networks[n].networkId)==1) { myn = n; break; }\n                    }\n                    \n                    if (userdata.networks) {\n                        \n                        if (userdata.networks[myn].server) { mqttServer = userdata.networks[myn].server; }\n                        if (userdata.networks[myn].port) { mqttPort = userdata.networks[myn].port; }\n                        if (userdata.networks[myn].user) { mqttUser = userdata.networks[myn].user; }\n                        if (userdata.networks[myn].ssl) { mqttSSL = userdata.networks[myn].ssl; }\n                        if (userdata.networks[myn].password) { mqttPassword = userdata.networks[myn].password; }\n                        \n                        \n\n                    }\n                    \n                    var sselect = '<select  id=\"serverserver\" name=\"serverserver\" onchange=\"changeserver()\">';\n                    \n                    \n                    \n                    for (var n in userdata.networks) {\n                        \n                        sselect += '<option value=\"' +  n + '\"' + (n==myn?\" selected\":\"\") + '>' +  userdata.networks[n].server + '</option>';\n                    }\n                    \n                    \n                    sselect += '</select>';\n                    document.getElementById(\"sselectdiv\").innerHTML = sselect ;\n                    \n                    connectMQTT();\n                    \n                    //$(ftarget).html(returnhtml);               \n                }           \n            });    \n            \n        // });\n        \n      \n        \n    };\n\t\n\n\n\nfunction onConnect() {\n  // Once a connection has been made, make a subscription and send a message.\n  console.log(\"onConnect\");\n  \n  document.getElementById(\"infodiv\").innerHTML = \"Connected\";\n\n  \n\n    if (urlParams.get('show').length>3) {\n\n        var shs = urlParams.get('show').split(\",\");\n        for (var sssh in shs) {\n            \n          var subtop = shs[sssh];\n          var tops = shs[sssh].split(\"/\");\n          for (var t in tops) {\n              if (tops[t]==\"\") { tops[t]=\"+\"; }\n          }\n          if (tops[tops.length-1]==\"+\") { tops[tops.length-1] = \"#\"; }\n          subtop=\"\";\n          for (var t in tops) {\n              subtop += (subtop==\"\"?\"\":\"/\") + tops[t];\n          }     \n          console.log(\"Subscribing to \" + subtop) ;\n          client.subscribe(subtop); \n          \n          subscriptions += \" \" + subtop;\n       \n        }   \n    } else {\n        \n        \n        client.subscribe(\"+/+/+/stat/state\"); \n        client.subscribe(\"+/+/+/+/plot\");\n        client.subscribe(\"+/+/+/+/property\");\n        client.subscribe(\"+/+/+/settings/title\");\n    }\n  \n\n \n}\n\n// called when the client loses its connection\nfunction onConnectionLost(responseObject) {\n  if (responseObject.errorCode !== 0) {\n    console.log(\"onConnectionLost:\"+responseObject.errorMessage);\n}\n}\n\n\nvar peakTot = 0;\nvar peakTotNo = 0;\nvar peakInd = 0;\nvar panelwidths = {};\nvar devcounts = {};\nvar devcount=0;\n\n// called when a message arrives\nfunction onMessageArrived(message) {\n  console.log(message.destinationName + \":\"+message.payloadString);\n  try { \n      \n      var ttt = new Date().getTime();\n      \n      var topics = message.destinationName.split(\"/\");\n\n    \n    var testexist =  document.getElementsByClassName(\"text_\"+topics[0]+\"_\"+topics[2]+\"_\"+topics[3]+\"_\"+topics[4]);\n\t\tfor (var i = 0; i < testexist.length; i++) {\n\t\t\t\n\t\t\tvar\tstyleplus = \" \" + testexist[i].getAttribute('styleplus') || \"\";\t\n\t\t\tif (styleplus.indexOf(\"integer\")>0) {\n\t\t\t\t\n\t\t\t\ttestexist[i].innerHTML = Math.round(parseFloat(message.payloadString));\n\t\t\t\t\n\t\t\t} else  if (styleplus.indexOf(\"shortstate\")>0) {\n\t\t\t\t\n\t\t\t\tvar ss = message.payloadString;\n\t\t\t\tif (ss==\"1\") { ss = \"on\"; }\n\t\t\t\telse if (ss==\"0\") { ss = \"\"; }\n\t\t\t\telse if (ss!==\"ok\" && ss!==\"off\" && ss!==\"on\" && ss!==\"run\") {\n\t\t\t\t    \n\t\t\t\t    if (ss.indexOf(\"arning\")>0) { ss = \"warn\"; } else { ss = \"alarm\"; }\n\t\t\t\t}\n\t\t\t\ttestexist[i].innerHTML = ss;\n\t\t\t\t\n\t\t\t} else  if (styleplus.indexOf(\"hidenormal\")>0) {\n\t\t\t\t\n\t\t\t\tvar ss = message.payloadString;\n\t\t\t\tif (ss==\"ok\" || ss==\"off\" || ss==\"on\" || ss==\"run\") { ss = \"\"; }\n\t\t\t\t\n\t\t\t\ttestexist[i].innerHTML = ss;\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\n\t\t\t\ttestexist[i].innerHTML = message.payloadString.replace(/_/g, ' ');;\n\t\t\t}\n\t}\n\t\n\t\n\t\t\t\t\t\n\tvar testexist6 = document.getElementsByClassName(\"bar_\"+topics[0]+\"_\"+topics[2]+\"_\"+topics[3]+\"_\"+topics[4]);\n\tfor (var i = 0; i < testexist6.length; i++) {\n\n\t\t//testexist6[i].width = 999; //parseFloat(testexist6[i].width) * item[1] / 100;\n\t\tvar newW = parseFloat(message.payloadString);\n\t\tvar barmax = parseFloat(testexist6[i].getAttribute(\"bmax\") || 100);\n\t\tnewW = newW * (barmax / 100);\n\t\t\n\t\tif (newW < -55555) { testexist6[i].setAttribute(\"x\", newW - 5); newW = 5; }\n\t\telse { testexist6[i].setAttribute(\"x\", 0); }\n\t\ttestexist6[i].setAttribute(\"width\", newW);\n\n\t}\n\t\t\t\t\t\n\t\n    \n  } catch {}\n  \n}\n\n\n\n\n\n\n\n\n\n\n\n// =========================================================================================================================\n\n</script>\n\n\n\n<section id=\"mqttsec\">\n<div id=\"controller\" class=\"controller\">   \n<table width=\"100%\"><tr><td>\n    \n    \n    <h3>Data Table</h3>\n   \n    </td><td align=\"right\">\n       \n     <span id=\"sselectdiv\"></span> \n    <span id=\"statusdiv\"></span>&nbsp;&nbsp; \n    <span id=\"infodiv\"></span> \n\n    \n</td><td align=\"right\">\n     <div id=\"mqttform\">\n    <form method=\"GET\">\n        <!--<small>Server:  </small><input style=\"width:200px;\" id=\"mqttServer\" name=\"server\" value=\"{{server}}\"> : <input style=\"width:100px;\" id=\"mqttPort\" name=\"port\" value=\"{{port}}\">-->\n        <!--<input style=\"width:150px;\" id=\"mqttUser\" name=\"user\" value=\"{{user}}\">-->\n        <!--<input type=\"password\" style=\"width:150px;\" id=\"mqttPassword\" name=\"password\" value=\"{{password}}\">-->\n        <!--<input  type=\"submit\" value=\"Connect\">-->\n        <input  id=\"show\" name=\"show\" type=\"hidden\" value=\"\">\n    </form>\n    </div> \n    \n</td></tr></table>\n\n\n</div>\n<script>\n    document.getElementById(\"show\").value = urlParams.get('show'); //\n    // document.getElementById(\"mqttServer\").value = mqttServer;\n    // document.getElementById(\"mqttPort\").value = mqttPort;\n    // document.getElementById(\"mqttUser\").value = mqttUser;\n    // document.getElementById(\"mqttPassword\").value = mqttPassword;\n    \n\n    //\n</script>\n\n\n\n\n\n<br>\n  \n  <div id=\"dtablediv\" class=\"dtable\" style=\"display:none\">Please wait...</div>\n  \n  \n\n</section>  \n","output":"str","x":380,"y":2760,"wires":[["ee55a2af.c6b07","284b663e.ad1e1a"]]},{"id":"ee55a2af.c6b07","type":"change","z":"513581b9.a1b88","name":"","rules":[{"t":"set","p":"sections.livetable","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":631,"y":2760,"wires":[[]]},{"id":"284b663e.ad1e1a","type":"function","z":"513581b9.a1b88","name":"","func":"msg.filename = global.get(\"htmlDirectory\") + \"/sections/livetable.html\";\nmsg.payload = msg.payload.body;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":2820,"wires":[["8139eab3.ea4d78"]]},{"id":"8139eab3.ea4d78","type":"file","z":"513581b9.a1b88","name":"","filename":"","appendNewline":false,"createDir":false,"overwriteFile":"true","encoding":"none","x":740,"y":2820,"wires":[[]]}]